#pragma once

#include <iostream>
#include <cstring>
#include <time.h>
#include <vector>

#define Die(code)   \
    do              \
    {               \
        exit(code); \
    } while (0)

#define CONV(v) (struct sockaddr *)(v)

enum
{
    USAGE_ERR = 1,
    SOCKET_ERR,
    BIND_ERR,
    LISTEN_ERR
};

const int gdefaultsockfd = -1;
const int gbacklog = 8;

bool ParseOneLine(std::string &str, std::string *out, const std::string &sep)
{
    auto pos = str.find(sep);
    if(pos == std::string::npos) return false;
    *out = str.substr(0, pos);
    str.erase(0, pos + sep.size());
    return true;
}

bool SplitString(const std::string &herder, const std::string &Sep, std::string *key, std::string *value)
{
    auto pos = herder.find(Sep);
    if(pos == std::string::npos) return false;
    *key = herder.substr(0, pos);
    *value = herder.substr(pos + Sep.size());
    return true;
}

std::string GetMonthName(int month)
{
    std::vector<std::string> months = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
    return months[month];
}

std::string GetWeekDayName(int day)
{
    std::vector<std::string> weekdays = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
    return weekdays[day];
}

std::string ExpireTimeRfc1123(int t)   // 秒级别的未来UTC时间
{
    time_t timeout = time(nullptr) + t;
    struct tm *tm = gmtime(&timeout);       // 这里不能用localtime，因为localtime是默认带了时区的，gmtime获取的就是UTC统一时间
    char timebuffer[1024];
    // 时间格式如：expires=Thu, 18, Dec, 2025, 12:00::00 UTC
    snprintf(timebuffer, sizeof(timebuffer), "%s, %02d %s %d %02d:%02d:%02d UTC", 
        GetWeekDayName(tm->tm_wday).c_str(),
        tm->tm_mday,
        GetMonthName(tm->tm_mon).c_str(),
        tm->tm_year + 1900,
        tm->tm_hour,
        tm->tm_min,
        tm->tm_sec
    );
    return timebuffer;
}